package com.github.ghsea.sso.client.security.cas;

import com.alibaba.fastjson.JSON;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Optional;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author guhai
 */
public class WebUtil {

    private static Logger log = LoggerFactory.getLogger(WebUtil.class);

    public static final String ORIGIN_URL_PARAMETER = "originUrl";

    private static final String REQUEST_CONTEXT = "requestContext";

    private static final String HEADER_KEY_SESSION_TYPE = "st";

    private static final String HEADER_VALUE_SESSION_TYPE = "token";

    public static void saveOriginUrl(final ServletRequest request) {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String originUrl = httpRequest.getParameter(ORIGIN_URL_PARAMETER);
        if (originUrl != null) {
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession();
            session.setAttribute(ORIGIN_URL_PARAMETER, originUrl);
        }
    }

    public static void clearOriginUrl(final ServletRequest request) {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession(false);
        session.removeAttribute(ORIGIN_URL_PARAMETER);
    }

    public static Optional<String> getOriginUrlQueryPath() {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession(false);
        if (session == null) {
            return Optional.empty();
        }

        String originUrl = (String) session.getAttribute(ORIGIN_URL_PARAMETER);
        if (originUrl == null) {
            return Optional.empty();
        }
        return Optional.of("?" + ORIGIN_URL_PARAMETER + "=" + originUrl);
    }

    public static Optional<String> getOriginUrl(final ServletRequest request) {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String originUrl = httpRequest.getParameter(ORIGIN_URL_PARAMETER);
        return Optional.ofNullable(originUrl);
    }

    public static Optional<String> getOriginUrl() {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession(false);
        String originUrl = (String) session.getAttribute(ORIGIN_URL_PARAMETER);
        return Optional.ofNullable(originUrl);
    }

    public static void holdRequestContext(final ServletRequest request, RequestContext context) {
        request.setAttribute(REQUEST_CONTEXT, context);
    }

    public static Optional<RequestContext> getRequestContext(final ServletRequest request) {
        RequestContext context = (RequestContext) request.getAttribute(REQUEST_CONTEXT);
        return Optional.ofNullable(context);
    }

    public static String getAuthTokenFromHeader(final ServletRequest request) {
        HttpServletRequest req = (HttpServletRequest) request;
        return req.getHeader(HEADER_VALUE_SESSION_TYPE);
    }

    /**
     * 判断session方式是使用cookie还是token
     *
     * @param request
     * @return
     */
    public static boolean isTokenSession(final ServletRequest request) {
        HttpServletRequest req = (HttpServletRequest) request;
        return StringUtils.endsWithIgnoreCase(req.getHeader(HEADER_KEY_SESSION_TYPE), HEADER_VALUE_SESSION_TYPE);
    }

    public static void writeJson(Map<?, ?> data, final ServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        try (PrintWriter out = response.getWriter()) {
            out.append(JSON.toJSONString(data));
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

}
